
package tictactoe.game;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;


public class TicTacToEd extends JFrame {
        private Model model;
        private ControllerInterface gm;
        private boolean playGame = false;
        
        final Icon empty = new ImageIcon("images/empty_tile.gif");
        final Icon cross = new ImageIcon("images/x_sign.gif");
        final Icon nought = new ImageIcon("images/o_sign.gif");
       
        protected static int X = 3, Y = 3;
       
        private JPanel topPanel, mainPanel, bottomPanel;
        private JLabel labelO, sep, labelX, thinkingL,thinkingR;
        protected JLabel scoreX, scoreO, round;
        private JLabel[][] gridView;
        int result;
        private boolean fl=false;
       
       
        public TicTacToEd() {
                model = new Model(X, Y);
                initComponents();
                playGame = true;
                int choice = askGameModeChoice();
                switch(choice)
                {
                case 0: gm = new HvH(model); break;
                case 1: gm = new HvC(model); break;
                case 2: gm = new CvC(model); playGame = false; simulateGame();
                }
        }
       
        private int askGameModeChoice()
        {
                Object[] options = {"Human vs Human",
                "Human vs Computer",
                "Computer vs Computer"};
                return JOptionPane.showOptionDialog(this,
                                "Select your game",
                                "Game Mode",
                                JOptionPane.YES_NO_CANCEL_OPTION,
                                JOptionPane.QUESTION_MESSAGE,
                                null,
                                options,
                                options[0]);
               
        }
       
//set initial components we have in the main game
        public void initComponents() {
		this.setIconImage(Toolkit.getDefaultToolkit().getImage("images/icon.gif"));      
                this.setTitle("TicTacToEd");
                this.setDefaultCloseOperation(EXIT_ON_CLOSE);
                this.setLayout(new BorderLayout());
                this.setResizable(true);      
                // menubar
                this.setJMenuBar(createJMenuBar());

                // topPanel
                topPanel = new JPanel();
                round = new JLabel(String.format("Round %d", 1));
                topPanel.add(round);
                this.add(topPanel, BorderLayout.NORTH);
               
                // mainPanel
                mainPanel = new JPanel(new GridLayout(3, 3, 20, 20));
                gridView = createGrid(mainPanel);              
                this.add(mainPanel, BorderLayout.CENTER);    
               
                //bottom panel              
                bottomPanel = new JPanel();
                labelO = new JLabel("<html><font color='green'>O</font></html>");
                scoreO = new JLabel("  0");
                sep = new JLabel("  |  ");
                labelX = new JLabel("<html><font color='red'>X</font></html>");
                scoreX = new JLabel("0  ");
                thinkingL = new JLabel("");
                thinkingR = new JLabel("");
                
                
                bottomPanel.add(thinkingL);
                bottomPanel.add(labelO);
                bottomPanel.add(scoreO);
                bottomPanel.add(sep);
                bottomPanel.add(scoreX);
                bottomPanel.add(labelX);
                bottomPanel.add(thinkingR);
                this.add(bottomPanel, BorderLayout.SOUTH);

                pack();
        }
       
        public JMenuBar createJMenuBar() {
               
                //create menu bar in the top of window after title
                JMenuBar mainMenuBar;
                JMenu menuA, menuB;
                JMenuItem newGame, exit, credits;
                mainMenuBar = new JMenuBar();
                menuA = new JMenu("Game");
                menuA.setMnemonic(KeyEvent.VK_G);
                menuB = new JMenu("About");
                menuB.setMnemonic(KeyEvent.VK_A);
                mainMenuBar.add(menuA);
                mainMenuBar.add(menuB);

                // creating choices
                newGame = new JMenuItem("New Game", KeyEvent.VK_N);
                exit = new JMenuItem("Exit", KeyEvent.VK_E);
                credits = new JMenuItem("Credits",KeyEvent.VK_L);
                menuA.add(newGame);
                menuA.add(exit);
                menuB.add(credits);
                
                exit.addActionListener(new ActionListener(){
                	public void actionPerformed(ActionEvent arg0)
                	{
                		System.exit(0);
                	}
                });
                
                newGame.addActionListener(new ActionListener(){
                    public void actionPerformed(ActionEvent arg0)
                    {
                    	for (int i = 0; i < model.getX(); i++)
                           	for (int j = 0; j < model.getY(); j++)
                           		gridView[i][j].setIcon(empty);
                     	model.setRound(1);
                     	model.setScoreX(0);
                     	model.setScoreY(0);    	
                     	round.setText("Round 1" );
                     	scoreO.setText("  0");
                     	scoreX.setText("0  ");
                     	model = new Model(X, Y);
                     	int choice = askGameModeChoice();
                        switch(choice)
                        {
                        	case 0: playGame = true; gm = new HvH(model); break;
                        	case 1: playGame = true; gm = new HvC(model); break;
                        	case 2: gm = new CvC(model); playGame = false; simulateGame();
                        }
                    }
                });
                
                credits.addActionListener(new ActionListener(){
                	public void actionPerformed(ActionEvent arg0)
                	{
                		JOptionPane.showMessageDialog(null,"", "Credits", JOptionPane.INFORMATION_MESSAGE, new ImageIcon("images/logo.jpg"));
                	}
                });
                              
                
                return mainMenuBar;
        }
        
        
        
        private void simulateGame()
        {
            gm.play(0);
            gridView[CvC.retX][CvC.retY].setIcon(cross);
            Timer timer;
            timer = new Timer(1000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent evt)
                {                    
                    int turn = gm.getTurn();
                    result = gm.makeMove(0, 0, 0);
                    if (result == -1) 
                        showMessage("Position Occupied");
                    else
                    {
                        if (turn == 1) 
                            gridView[CvC.retX][CvC.retY].setIcon(cross);
                        else 
                            gridView[CvC.retX][CvC.retY].setIcon(nought);

                        if (result == 3) {                             
                            ((Timer)evt.getSource()).stop();
                            if(showMessageWithResponse("Tie") == 0)
                            {
                                clear();
                                simulateGame();
                                //((Timer)evt.getSource()).restart();
                            }                            
                        }
                        else if (result == 1) 
                        {                             
                            ((Timer)evt.getSource()).stop();
                            if(showMessageWithResponse("Computer 1 wins") == 0)
                            {
                                clear();
                                simulateGame();
                                //((Timer)evt.getSource()).restart();
                            }
                        }
                        else if (result == 2) 
                        {                             
                            ((Timer)evt.getSource()).stop();
                            if(showMessageWithResponse("Computer 2 wins") == 0)
                            {
                                clear();
                                simulateGame();
                                //((Timer)evt.getSource()).restart();
                            }
                        }
                    } // else             
                }                
            });
            timer.start();
        	
        	
        	
        }
        
        public JLabel[][] createGrid(JPanel panel)
        {
        	gridView = new JLabel[model.getX()][model.getY()];
                
            for (int i = 0; i < model.getX(); i++)
            {
            	for (int j = 0; j < model.getY(); j++)
                	{
                    	final int internalI = i, internalJ = j;
                               
                        gridView[i][j]=new JLabel(empty);
                        mainPanel.add(gridView[i][j]);
                        gridView[i][j].addMouseListener(new MouseListener() {
                       
                        	@Override
                        	public void mouseClicked(MouseEvent e) {
                        		if(playGame)
                        		{                        			
                        			if (gm instanceof HvC)
                        			{
                        				//human (in HvC actually computer starts - turned around)
                        				result = gm.makeMove(internalI, internalJ, 1);
                        				if (result == -1) { showMessage("Position Occupied");fl=true;}
                        				else
                        				{
                        					gridView[internalI][internalJ].setIcon(cross);
                                                   		
                        					if (result == 3) { showMessage("Tie");clear();}
                        					else
                        					if (result == 2) { showMessage("Computer wins");clear();}
                        					else 
                        					if (result == 1) { showMessage("Human wins");clear();}
                        				}
                        				//computer
                        				if (playGame && !fl)
                        				{
                        					result = gm.makeMove(0, 0, 2);
                        					if (result == -1) showMessage("Position Occupied");
                        					else
                        					{
                        						gridView[HvC.retX][HvC.retY].setIcon(nought);
                                                   		
                        						if (result == 3) { showMessage("Tie");clear();}
                        						else
                        						if (result == 2) { showMessage("Computer wins");clear();}
                        						else 
                        						if (result == 1) { showMessage("Human wins");clear();}
                        					}
                        				}
                        				fl=false;
                        			}
                        			else
                       				if (gm instanceof HvH)
                        			{
                        				int turn = gm.getTurn();
                        				result = gm.makeMove(internalI, internalJ, turn);
                        				if (result == -1) showMessage("Position Occupied");
                        				else
                        				{
                        					if (turn == 1) gridView[internalI][internalJ].setIcon(cross);
                        					else gridView[internalI][internalJ].setIcon(nought);
                                                   		
                        					if (result == 3) { showMessage("Tie");clear();}
                        					else
                        					if (result == 1) { showMessage("Player 1 wins");clear();}
                        					else 
                        					if (result == 2) { showMessage("Player 2 wins");clear();}
                        				}
                        			}
                        		}                      		             
                        	}

                            @Override
                            public void mouseEntered(MouseEvent arg0) {
                            	// TODO Auto-generated method stub
                            }

                            @Override
                            public void mouseExited(MouseEvent arg0) {
                            	// TODO Auto-generated method stub
                            }

                            @Override
                            public void mousePressed(MouseEvent arg0) {
                            	// TODO Auto-generated method stub
                            }

                            @Override
                            public void mouseReleased(MouseEvent arg0) {
                            	// TODO Auto-generated method stub
                            }

                        });
                    }
            }
            return gridView;
        }
        
        private void clear()
        {
        	 for (int i = 0; i < model.getX(); i++)
                    for (int j = 0; j < model.getY(); j++)
               		gridView[i][j].setIcon(empty);
        	 model.increaseRound();
        	 round.setText("Round " + (model.getRound()));
        	 if (result == 1) 
                     model.increaseScoreX();
        	 else
        	 if (result == 2) 
                     model.increaseScoreY();
        	 scoreO.setText("  " + Integer.toString(model.getScoreY()));
        	 scoreX.setText(Integer.toString(model.getScoreX()) + "  ");
                 model.clear();
        	 
        }

        private void showMessage(String message)
        {
                JOptionPane.showMessageDialog(this, message,"Result",JOptionPane.PLAIN_MESSAGE);
        }
        
        private int showMessageWithResponse(String message)
        {
                Object[] options = {"Yes", "No"};
                return JOptionPane.showOptionDialog(this,
                                message + "\nDo you want to play again?",
                                "Result",
                                JOptionPane.YES_NO_CANCEL_OPTION,
                                JOptionPane.QUESTION_MESSAGE,
                                null,
                                options,
                                options[0]);
        }
        
        public static void main(String args[]) {

                TicTacToEd fv = new TicTacToEd();

                fv.setVisible(true);

        }

}